
#region copyright notice
/* ====================================================================
 * The UncleGED Open Source Software License
 *
 * Copyright (c) 1999-2009 D. M. DeBacker. All rights reserved.
 * http://gatheringleaves.org/uged
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. Products derived from this software may not be called "UncleGED",
 *    nor may "UncleGED" appear in their name, without prior written
 *    permission of D. M. DeBacker.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL D. M. DEBACKER BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */
#endregion


#define TEST
//un-commenting the above will allow for easier debugging

using System;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using UncleGED;
using UncleGED.Utils;
using UncleGED.Application;
using System.Reflection;

namespace UGed
{

	/// <summary>
	/// Contains the main function
	/// </summary>
	public class StartUp
	{
		//these flags are left over from UG 5 and are no longer used
		//public bool bUseXML;
		//public bool bUseBook;
		//public bool bUseCatalog;
		//public bool bStartUp;

		//these contstants are left over from UG 5 and are no longer used
		//public const short WO_READONLY = 0;
		//public const short WO_WRITEHTML = 1;
		//public const short WO_WRITECATALOG = 2;
		//public const short WO_WRITEBOTH = 3;
		

		//global stream writer for the log file
		public static StreamWriter g_sw;

		/// <summary>
		/// The is where the progam starts
		/// </summary>
		/// <param name=Args></param>
		/// 		
		public static int Main(string[] Args) 
		{

			string  gedcomFile = "";
			string  configXmlFile = "";
			GedReader  gr; 
			TimeSpan tsStart;
			TimeSpan tsStop;
			double totalTime;
			int retVal = 0;
			bool _RssForSS = false;

			//read the default settings from the xml config file
			UGedProject configSettings =  new UGedProject();
			LocalApplication localSettings = new LocalApplication();
			
			//string funcs class contains functions ported from VB6
			//see notes in read-me
			StringFunctions sf = new StringFunctions();

			//one purpose of TEST is to turn off the try-catch block in this 
			//and allow the debugger to trigger in case of an error
#if (!TEST)
			try 
			{
#endif
				//start a log file
				string  sPath = FolderMethods.GetAppPath(); 
				string  sLogFile = sPath + "\\uged.log";
				g_sw = new System.IO.StreamWriter(sLogFile);
				Trace.Listeners.Add(new TextWriterTraceListener(g_sw));
				Trace.AutoFlush = true;

				configSettings = new UGedProject();
            localSettings = ConfigReader.LoadSettings(sPath + "\\projects.cfg");

				//write out the version
				Console.Write(System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).ProductName + " - Ver. " + Assembly.GetExecutingAssembly().GetName().Version.ToString());

#if (DEBUG) 
				Console.WriteLine(" (DEBUG)");
#else 
	Console.WriteLine(" (RELEASE)");
#endif
				Tools.Logit("GEDCOM-To-HTML");
            Tools.Logit(System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).LegalCopyright);


				//process the command line and override config as needed
				int iCnt;
				string  cmdSwitch = "";
				string  cmdData = "";

				if ( Args.Length > 0 ) 
				{
					for ( iCnt = 0 ; iCnt <= Args.GetUpperBound(0); iCnt++)
					{

						try 
						{
							if ( Args[iCnt].Length == 3 ) 
							{
								cmdSwitch = sf.Left(Args[iCnt], 3);
							} 
							else 
							{
								cmdSwitch = sf.Left(Args[iCnt], 2);
							}
						} 
						catch 
						{
							PrintUsage(false, configSettings);
							retVal = -1;
							goto END_THIS_THING;
						}

						if ( cmdSwitch.Length == 2 ) 
						{
							try 
							{
								cmdData = sf.Right(Args[iCnt], sf.Len(Args[iCnt]) - 2);
							} 
							catch 
							{
								cmdData = "";
							}
						}

						switch (cmdSwitch)
						{
							case "/f" : gedcomFile = cmdData; break;
							case "/c" : configXmlFile = cmdData; break;
							case "/?": 
								PrintUsage(true,configSettings);
								retVal = 0;
								goto END_THIS_THING;
							case "/w" :
								//the following will create a default config file
								configXmlFile = "_default.ugproj";
								retVal = -1;
								goto END_THIS_THING;
							case "-ac" : configSettings.AddUserCopyright = ! configSettings.AddUserCopyright;break;
							case "-ak" : configSettings.AddKeywords = ! configSettings.AddKeywords;break;
                     case "-an" : configSettings.AddSpaceToConc = !configSettings.AddSpaceToConc; break;
							case "-as" : configSettings.AddSurnameCount = ! configSettings.AddSurnameCount;break;
							case "-cl" : configSettings.ChronoLinks = ! configSettings.ChronoLinks;break;
							case "-cp" : configSettings.CreateChronoPage = ! configSettings.CreateChronoPage;break;
							case "-cs" : configSettings.UseCSS = ! configSettings.UseCSS; break;
							case "-de" : configSettings.DoDateEstimation = ! configSettings.DoDateEstimation;break;
							case "-dm" : configSettings.DisplayMRIN = ! configSettings.DisplayMRIN;break;
							case "-dr" : configSettings.DisplayRIN = ! configSettings.DisplayRIN;break;
							case "-gf" : configSettings.CreateGendexFile = ! configSettings.CreateGendexFile;break;
							case "-hr" : configSettings.HiLiteMostRecent = ! configSettings.HiLiteMostRecent;break;
							case "-io" : configSettings.IgnoreOccupations = ! configSettings.IgnoreOccupations;break;
							case "-ld" : configSettings.LocDisplayEventDates = ! configSettings.LocDisplayEventDates;break;
							case "-lo" : configSettings.LocReverseOrder = ! configSettings.LocReverseOrder;break;
							case "-lp" : configSettings.CreateLocPage = ! configSettings.CreateLocPage;break;
							case "-lr" : configSettings.CreateListReport = ! configSettings.CreateListReport;break;
							case "-lt" : configSettings.OccLocEqualsOccText = ! configSettings.OccLocEqualsOccText;break;
							case "-mi" : configSettings.MostRecentOnIndex = ! configSettings.MostRecentOnIndex;break;
							case "-mp" : configSettings.MostRecentOnPage = ! configSettings.MostRecentOnPage;break;
							case "-op" : configSettings.CreateOccupationsPage = ! configSettings.CreateOccupationsPage;break;
							case "-pr" : configSettings.Privacy = ! configSettings.Privacy;break;
							case "-sc" : configSettings.SurnamesAllCaps = ! configSettings.SurnamesAllCaps;break;
							case "-sp" : configSettings.CreateStatsPage = ! configSettings.CreateStatsPage;break;
                     case "-st" : configSettings.LocStripTrailingPunc = !configSettings.LocStripTrailingPunc; break;
							case "-ub" : configSettings.UseBackground = ! configSettings.UseBackground;break;
							case "-ur" : configSettings.UseBanner = ! configSettings.UseBanner;break;
                     case "-ut": configSettings.UseTagToText = !configSettings.UseTagToText; break;
							//case "-wa" : configSettings.WarnNonAnsi = ! configSettings.WarnNonAnsi;break;
							case "-xl" : configSettings.ExcludeLivingIndividualsAfterBirthCutOff = ! configSettings.ExcludeLivingIndividualsAfterBirthCutOff;break;
							case "-xn" : configSettings.ExcludeNotes = ! configSettings.ExcludeNotes;break;
							case "-b" : if ( cmdData.Length != 0 )   configSettings.BackgroundFile = cmdData;break;
							case "-c" : if ( cmdData.Length != 0 )   configSettings.ChronoCutOff = System.Convert.ToInt16(cmdData);break;
							case "-e" : if ( cmdData.Length != 0 )   configSettings.AuthorsEmail = cmdData;break;
							case "-g" : if ( cmdData.Length != 0 )   configSettings.GedcomPath = cmdData;break;
							case "-h" : if ( cmdData.Length != 0 )   configSettings.HtmlPath = cmdData;break;
                     case "-m" : if ( cmdData.Length != 0 )   configSettings.MaxIndPerPage = System.Convert.ToInt16(cmdData); break;
							case "-n" : if ( cmdData.Length != 0 )   configSettings.AuthorsName = cmdData;break;
							case "-p" : if ( cmdData.Length != 0 )   configSettings.FamFilePrefix = cmdData;break;
							case "-r" : if ( cmdData.Length != 0 )   configSettings.BannerFile = cmdData;break;
							case "-s" : if ( cmdData.Length != 0 )   configSettings.LocEstimateMethod = System.Convert.ToInt16(cmdData);break;
							case "-t" : if ( cmdData.Length != 0 )   configSettings.MainPageTitle = cmdData;break;
							case "-u" : if ( cmdData.Length != 0 )   configSettings.AuthorsUrl = cmdData;break;
							case "-y" : if ( cmdData.Length != 0 )   configSettings.BirthCutOffYears = System.Convert.ToInt16(cmdData);break;
                     case "-W": if (cmdData.Length != 0) configSettings.PageStyle = System.Convert.ToInt16(cmdData); break;
							case "-rs": _RssForSS = true; break;
						}
					} //
				} 
				else 
				{
					PrintUsage(false, configSettings);
					retVal = -1;
					goto END_THIS_THING;
				}

				if ( gedcomFile.Length == 0 ) 
				{
					PrintUsage(false, configSettings);
					retVal = -1;
					goto END_THIS_THING;
				} 
				else 
				{
					if ( configXmlFile.Length == 0 ) 
					{
                  configXmlFile = "_default.ugproj";
					} 
					else 
					{
						Tools.Logit("Reading Configuration from...");
						Tools.Logit(configXmlFile);
						configSettings = LoadXmlSettings(configXmlFile);
					}

					if (! (configSettings == null) ) 
					{
						Tools.Logit("Processing " + gedcomFile);
						tsStart = DateTime.Now.TimeOfDay;

						//the GED reader object does all the work
						// see ug_gedreader.cs
						gr = new GedReader(configSettings, localSettings, gedcomFile, _RssForSS);

                  gr.StatusMessage += new StatusMessageEventHandler(GedReader_StatusMessage);

						//process the data
						if ( gr.ProcessGedComFile(gedcomFile, true) == true ) 
						{
							if ( configSettings.DoDateEstimation == true ) 
							{
								gr.EstimateBirthDates();
							}

							if ( configSettings.DoDateEstimation == true ) 
							{
								Tools.Logit("Saving estimated dates listing file...");
								gr.SaveEstimatedDatesList();
							}

							if ( configSettings.ExcludeLivingIndividualsAfterBirthCutOff == true ) 
							{
								gr.ExcludeLivingIndividuals();
							}
							
							//write out the HTML files
							gr.SaveAsHTM();
						} 
						else 
						{
							retVal = -1;
							goto END_THIS_THING;
						}
						tsStop = DateTime.Now.TimeOfDay;
						totalTime = tsStop.TotalSeconds - tsStart.TotalSeconds;
						Tools.Logit("Total time to process: " + totalTime.ToString()  + " seconds");
					} 
					else 
					{
						Tools.Logit("Error Processing XML config file!");
						retVal = -1;
						goto END_THIS_THING;
					}

				}
				Tools.Logit("Thank you for using Uncle GED...");
				Tools.Logit("Y\'all come back now, y\'hear!");

#if (!TEST)
			} 
			catch (Exception ex) 
			{
				Tools.Logit("Error trapped in Main : " + ex.Message);
				retVal = -1;
			}
#endif

			END_THIS_THING:
				try 
				{
					SaveXmlSettings(configXmlFile, configSettings);
				} 
				catch 
				{
					//empty catch
				}
			g_sw.Close();
			return retVal;
		}

      private static void GedReader_StatusMessage(object sender, StatusMessageArgs e)
      {
         Console.WriteLine(e.Message);
      }

		/// <summary>
		/// Summary of PrintUsage.
		/// </summary>
		/// <param name=bAll></param>
		/// <param name=configSettings></param>
		/// 		
      private static void PrintUsage(bool bAll, UGedProject configSettings) 
		{
			Console.WriteLine("USAGE: uged.exe /f[gedcom file] {/c[config]}|{options}");
			if ( bAll ) 
			{
				Console.WriteLine("/w" + '\t' + "- Used alone to create a default XML config file");
				Console.WriteLine("OPTIONS:");
				Console.WriteLine("BOOLEAN OPTIONS - These act as switches that reverses the default setting");
				Console.WriteLine("-ac" + '\t' + "- AddUserCopyright (default:" + configSettings.AddUserCopyright.ToString() + ")");
				Console.WriteLine("-ak" + '\t' + "- AddKeywords (default:" + configSettings.AddKeywords.ToString() + ")");
            Console.WriteLine("-an" + '\t' + "- AddSpaceToConc (default:" + configSettings.AddSpaceToConc.ToString() + ")");
				Console.WriteLine("-as" + '\t' + "- AddSurnameCount (default:" + configSettings.AddSurnameCount.ToString() + ")");
				Console.WriteLine("-cl" + '\t' + "- ChronoLinks (default:" + configSettings.ChronoLinks.ToString() + ")");
				Console.WriteLine("-cp" + '\t' + "- CreateChronoPage (default:" + configSettings.CreateChronoPage.ToString() + ")");
				Console.WriteLine("-de" + '\t' + "- DoDateEstimation (default:" + configSettings.DoDateEstimation.ToString() + ")");
				Console.WriteLine("-dm" + '\t' + "- DisplayMRIN (default:" + configSettings.DisplayMRIN.ToString() + ")");
				Console.WriteLine("-dr" + '\t' + "- DisplayRIN (default:" + configSettings.DisplayRIN.ToString() + ")");
				Console.WriteLine("-gf" + '\t' + "- CreateGendexFile (default:" + configSettings.CreateGendexFile.ToString() + ")");
				Console.WriteLine("-hr" + '\t' + "- HiLiteMostRecent (default:" + configSettings.HiLiteMostRecent.ToString() + ")");
				Console.WriteLine("-io" + '\t' + "- IgnoreOccupations (default:" + configSettings.IgnoreOccupations.ToString() + ")");
				Console.WriteLine("-ld" + '\t' + "- LocDisplayEventDates (default:" + configSettings.LocDisplayEventDates.ToString() + ")");
				Console.WriteLine("-lo" + '\t' + "- LocReverseOrder (default:" + configSettings.LocReverseOrder.ToString() + ")");
				Console.WriteLine("-lp" + '\t' + "- CreateLocPage (default:" + configSettings.CreateLocPage.ToString() + ")");
				Console.WriteLine("-lr" + '\t' + "- CreateListReport (default:" + configSettings.CreateListReport.ToString() + ")");
				Console.WriteLine("-lt" + '\t' + "- OccLocEqualsOccText (default:" + configSettings.OccLocEqualsOccText.ToString() + ")");
				Console.WriteLine("-mi" + '\t' + "- MostRecentOnIndex (default:" + configSettings.MostRecentOnIndex.ToString() + ")");
				Console.WriteLine("-mp" + '\t' + "- MostRecentOnPage (default:" + configSettings.MostRecentOnPage.ToString() + ")");
				Console.WriteLine("-op" + '\t' + "- CreateOccupationsPage (default:" + configSettings.CreateOccupationsPage.ToString() + ")");
				Console.WriteLine("-pr" + '\t' + "- Privacy (default:" + configSettings.Privacy.ToString() + ")");
				Console.WriteLine("-sc" + '\t' + "- SurnamesAllCaps (default:" + configSettings.SurnamesAllCaps.ToString() + ")");
				Console.WriteLine("-sp" + '\t' + "- CreateStatsPage (default:" + configSettings.CreateStatsPage.ToString() + ")");
            Console.WriteLine("-st" + '\t' + "- LocStripTrailingPunc (default:" + configSettings.LocStripTrailingPunc.ToString() + ")");
				Console.WriteLine("-ub" + '\t' + "- UseBackground (default:" + configSettings.UseBackground.ToString() + ")");
				Console.WriteLine("-ur" + '\t' + "- UseBanner (default:" + configSettings.UseBanner.ToString() + ")");
            Console.WriteLine("-ut" + '\t' + "- UseTagToText (default:" + configSettings.UseTagToText.ToString() + ")");
				//Console.WriteLine("-wa" + '\t' + "- WarnNonAnsi (default:" + configSettings.WarnNonAnsi.ToString() + ")");
				Console.WriteLine("-xl" + '\t' + "- ExcludeLivingIndividualsAfterBirthCutOff (default:" + configSettings.ExcludeLivingIndividualsAfterBirthCutOff.ToString() + ")");
				Console.WriteLine("-xn" + '\t' + "- ExcludeNotes (default:" + configSettings.ExcludeNotes.ToString() + ")");
				Console.WriteLine("");
				Console.WriteLine("COMMAND OPTIONS - These require additional input");
				Console.WriteLine("-b[BackgroundFile]  " + '\t' + "- BackgroundFile");
				Console.WriteLine("-c[ChronoCutOff]    " + '\t' + "- ChronoCutOff");
				Console.WriteLine("-e[AuthorsEmail]    " + '\t' + "- AuthorsEmail");
				Console.WriteLine("-h[HtmlPath]        " + '\t' + "- HtmlPath");
            Console.WriteLine("-m[MaxIndiPerPage]  " + '\t' + "- MaxIndiPerPage");
				Console.WriteLine("-n[AuthorsName]     " + '\t' + "- AuthorsName");
				Console.WriteLine("-p[FamFilePrefix]   " + '\t' + "- FamFilePrefix");
				Console.WriteLine("-r[BannerFile]      " + '\t' + "- BannerFile");
				Console.WriteLine("-s[0|1|2]           " + '\t' + "- LocEstimateMethod");
				Console.WriteLine("-t[MainPageTitle]   " + '\t' + "- MainPageTitle");
				Console.WriteLine("-u[AuthorsUrl]      " + '\t' + "- AuthorsUrl");
				Console.WriteLine("-y[BirthCutOffYears]" + '\t' + "- BirthCutOffYears");
            Console.WriteLine("-w[0|1]             " + '\t' + "- [Web]PageStyle");
				Console.WriteLine("");
				Console.WriteLine("HINT: uged /?| MORE displays Help one screen at a time.");
				Console.WriteLine("See the documentation for more details regarding uged options");
			} 
			else 
			{
				Console.WriteLine("HINT: uged /? to display options");
            Console.WriteLine("See the documentation for more details regarding uged options");
			}
		}

		/// <summary>
		/// Summary of SaveXmlSettings.
		/// </summary>
		/// <param name=sXmlConfig></param>
		/// <param name=ConfigSettings></param>
		/// 		
      public static void SaveXmlSettings(string sXmlConfig, UGedProject ConfigSettings) 
		{
			XmlSerializer  XmlS = new XmlSerializer(typeof(UGedProject));
			FileStream  fStream = new FileStream(sXmlConfig, FileMode.Create);

			XmlS.Serialize(fStream, ConfigSettings);
			fStream.Close();
		}

		/// <summary>
		/// Summary of LoadXmlSettings.
		/// </summary>
		/// <param name=sXmlConfig></param>
		/// 		
      public static UGedProject LoadXmlSettings(string sXmlConfig) 
		{
			UGedProject configSettings;

			try 
			{
				XmlSerializer  XmlS = new XmlSerializer(typeof(UGedProject));
				FileStream  fStream = new FileStream(sXmlConfig, FileMode.Open);
				configSettings = (UGedProject)XmlS.Deserialize(fStream);
				fStream.Close();
				fStream = null;
				XmlS = null;
			} 
			catch
			{
				configSettings = null;
			}

			return configSettings;

		}
	
	} 
}